﻿using System.Diagnostics;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using StaffWarsFm.Server;
using StaffWarsFm.Services;
using StaffWarsFm.Lib.Data;

namespace StaffWarsFm
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, IRadioServiceClient
    {
        private RadioViewModel viewModel = new RadioViewModel();
        private DuplexChannelFactory<IRadioService> channelFactory;
        private IRadioService radioService;
        private Grid currentScreen;

        public MainWindow()
        {
            InitializeComponent();

            DataContext = viewModel;
            ShowScreen(challengeScreen);
        }

        public RadioViewModel ViewModel
        {
            get { return viewModel; }
            private set
            {
                viewModel = value;
            }
        }

        public void Start(User currentUser, SpeakerMasterDetails speakerMaster)
        {
            var address = speakerMaster.Address;
            var serverUri = ServerAddressGenerator.GenerateServerAddress(address);
            var serverEndpointAddress = new EndpointAddress(serverUri);

            channelFactory = new DuplexChannelFactory<IRadioService>(
                this,
                "radioService",
                serverEndpointAddress);

            radioService = channelFactory.CreateChannel();

            radioService.GutenTag(currentUser);
        }

        #region Service Methods

        public void SetCurrentRadioMaster(User user)
        {
            Dispatcher.Invoke(delegate
                {
                    ViewModel.RadioMaster = user;

                    if (ViewModel.IsServer)
                    {
                        radio.PlayStation(user.UserName);
                    }

                    ShowScreen(challengeScreen);
                });
        }

        public void ChallengeRequest(User challeningUser)
        {
            Dispatcher.Invoke(delegate
                {
                    ViewModel.ChallengingUser = challeningUser;
                    ShowScreen(beingChallengedScreen);
                });
        }

        public void ChallengeResponse(bool canChallenge)
        {
            ViewModel.IsWorking = false;

            if (canChallenge)
            {
                ShowScreen(waitingForChallengeResponse);
            }
            else
            {
                MessageBox.Show("Challenge Not Allowed");
                ShowScreen(challengeScreen);
            }
        }

        public void GeneratingQuestion()
        {
            Dispatcher.Invoke(delegate
                {
                    ShowScreen(generatingQuestionScreen);
                });
        }

        public void AskQuestion(Question question)
        {
            Debug.WriteLine("Been Asked A Question");
            ViewModel.Question = question;
            ShowScreen(askQuestionScreen);
            Debug.WriteLine("Showing Question Screen");
        }

        #endregion

        private void Window_Closed(object sender, System.EventArgs e)
        {
            channelFactory.Close();
        }

        private void Challenge_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            ViewModel.IsWorking = true;
            radioService.Challenge(ViewModel.CurrentUser);
        }

        private void ShowScreen(Grid screen)
        {
            if (currentScreen != null)
                currentScreen.Visibility = Visibility.Collapsed;

            screen.Visibility = Visibility.Visible;
            currentScreen = screen;
        }

        private void DeclineChallenge_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            radioService.DeclineChallenge();
        }

        private void AcceptChallenge_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            radioService.AcceptChallenge();
        }

        private void SubmitAnswer_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            var answer = (Answer) e.Parameter;
            radioService.SubmitAnswer(answer.IsCorrect);

            ShowScreen(submittingAnswerScreen);
        }
    }
}
